package org.scboy.rbac.loads;

import org.scboy.common.cache.SystemConfig;
import org.scboy.coobi.sql.Coobi;
import org.scboy.coobi.sql.factory.EntityFactory;
import org.scboy.rbac.dao.RbacLoginSessionDao;
import org.scboy.rbac.dao.RbacLoginStateDao;
import org.scboy.rbac.dao.RbacOrgDao;
import org.scboy.rbac.dao.RbacOrgTypeDao;
import org.scboy.rbac.dao.RbacUserAccountDao;
import org.scboy.rbac.dao.RbacUserInfoDao;
import org.scboy.rbac.dao.RbacUserTypeDao;
import org.scboy.utils.caches.DataCache;
import org.scboy.utils.entitys.coobi.Model;
import org.scboy.utils.entitys.rbac.LoginAccount;
import org.scboy.utils.entitys.rbac.LoginUser;
import org.scboy.utils.entitys.rbac.Org;
import org.scboy.utils.entitys.rbac.OrgType;
import org.scboy.utils.entitys.rbac.UserInfo;
import org.scboy.utils.entitys.rbac.UserType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

/**
 * 组织缓存管理
 */
@Configuration
@EnableCaching
@AutoConfigureAfter(value = {Coobi.class,EntityFactory.class})
public class loadLoginUser implements DataCache<LoginUser> {
	
	Log log =LogFactory.get();

	@Autowired
	EntityFactory factory;

	@Autowired
	SystemConfig config;
	
	/**
	 * 获取缓存数据
	 * @return
	 */
	@Override
	@Cacheable(value="RBAC_LOGIN_CACHE",key="#token",unless="#result == null")
	public LoginUser get(String token) {
		
		RbacLoginStateDao stateDao=factory.getDao(RbacLoginStateDao.class);
		//检查登录状态是否正常
		if(stateDao.count(Model.create().add("sessionId", token).add("sessionState", 0))==0){
			//清楚相应的缓存
			SpringUtil.getBean(loadLoginUser.class).removeCache(token);
			return null;
		}
		
		RbacLoginSessionDao dao=factory.getDao(RbacLoginSessionDao.class);
		RbacUserInfoDao userDao=factory.getDao(RbacUserInfoDao.class);
		RbacUserTypeDao userTypeDao=factory.getDao(RbacUserTypeDao.class);
		RbacOrgDao orgDao=factory.getDao(RbacOrgDao.class);
		RbacOrgTypeDao orgTypeDao=factory.getDao(RbacOrgTypeDao.class);
		RbacUserAccountDao accountDao=factory.getDao(RbacUserAccountDao.class);
		
		LoginUser loginUser=new LoginUser();
		
		Model loginSession=dao.get(Model.create().add("id",token));
		//登录回话不存在。
		if(loginSession==null)return null;
		
		
		//登录返回信息封装
		loginUser.setToken(loginSession.getString("id"));
		loginUser.setTokenKey(config.getConfig("TOKEN_KEY"));
		loginUser.setLoginIp(loginSession.getString("loginIp"));
		loginUser.setLoginIps(loginSession.getString("loginIps"));
		loginUser.setLoginTime(loginSession.getDate("loginTime"));
		//获得登录的用户信息
		
		Model userInfoData=userDao.get(Model.create().add("id", loginSession.getString("userId")));
		
		UserInfo userInfo=userInfoData.toEntity(UserInfo.class);
		
		//获得登录的用户组织
		Model orgData=orgDao.get(Model.create().add("id", loginSession.getString("orgId")));
		
		if(orgData!=null) {
			
			initOrg(orgData);

			Org org=orgData.toEntity(Org.class);
			
			//查询组织类型
			Model orgType=orgTypeDao.get(Model.create().add("id", orgData.getString("orgType")));
			if(orgType!=null) {
				org.setOrgType(orgType.toEntity(OrgType.class));
			}
			
			userInfo.setOrg(org);
			
			int level=orgData.getInt("orgLevel");
			Model queryOrgData=getQueryOrg(orgData,level);
			
			if(queryOrgData!=null) {
				Org queryOrg=queryOrgData.toEntity(Org.class);
				//查询组织类型
				Model queryOrgType=orgTypeDao.get(Model.create().add("id", orgData.getString("orgType")));
				if(queryOrgType!=null) {
					queryOrg.setOrgType(queryOrgType.toEntity(OrgType.class));
				}
				userInfo.setQueryOrg(queryOrg);
			}
		}
		Model accountModel=accountDao.get(Model.create().add("userId", loginSession.getString("userId")).add("loginAccount", loginSession.getString("loginName")));
		//获得登录账号
		loginUser.setAccount(accountModel.toEntity(LoginAccount.class));
		Model userType=userTypeDao.get(Model.create().add("id", userInfoData.getString("userType")));
		if(userType!=null) {
			userInfo.setUserType(userType.toEntity(UserType.class));
		}
		
		loginUser.setUserInfo(userInfo);
		
		return loginUser;
	}
	
	/**
	 * 根据ID更新缓存
	 * @return
	 */
	@Override
	@CachePut(value="RBAC_LOGIN_CACHE",key="#entity.token",unless="#result == null")
	public LoginUser update(LoginUser entity) {
		return entity;
	}
	
	/**
	 * 根据ID更新缓存
	 * @param id
	 * @return
	 */
	@Override
	@CachePut(value="RBAC_LOGIN_CACHE",key="#token",unless="#result == null")
	public LoginUser updateByKey(String token) {
		return get(token);
	}
	
	/**
	 * 移除缓存
	 * @param id
	 * @return
	 */
	@Override
	@CacheEvict(value="RBAC_LOGIN_CACHE",key = "#token")
	public LoginUser removeCache(String token) {
		return null;
	}
	
	/**
	 * 清空所有缓存
	 * @return
	 */
	@Override
	@CacheEvict(value="RBAC_LOGIN_CACHE",allEntries = true)
	public void removeAll() {}
	

	public void initOrg(Model org) {
		if(StrUtil.isBlank(org.getString("orgShortName"))) {
			org.add("orgShortName", org.getString("orgLocation"));
		}
	}
	
	public Model getQueryOrg(Model org,int orgLevel) {
		RbacOrgDao dao=factory.getDao(RbacOrgDao.class);
		Model parent=dao.get(Model.create().add("id", org.getString("parentId")).add("orgLevel", orgLevel));
		if(parent!=null) {
			return getQueryOrg(parent, orgLevel);
		}else {
			initOrg(org);
			return org;
		}
	}
}
